﻿using ASmile.Com.MenuRole;
using ASmile.DBModel;
using ASmile.Extend;
using ASmile.ORM.Cores;

namespace ASmile.Com.Da
{
    public class MenuRoleBLL : BLLBase, IMenuRoleBLL
    {
        public MenuRoleBLL()
        {
            DaRole = CreateBLL<RoleBLL>();
        }

        #region 角色维护

        RoleBLL DaRole { get; }

        protected ApiResult<string> RoleVerifyModel(Sys_Role model, bool isAdd)
        {
            if (model.RoleName.IsEmpty())
            {
                return ApiResult.RetErr(Sys_Role.CNRoleName, "角色名称不能为空");
            }
            if (DB.QueryExist<Sys_Role>(s => s.RoleName == model.RoleName && s.Id != model.Id))
            {
                return ApiResult.RetErr(Sys_Role.CNRoleName, "角色名称重复");
            }
            if (isAdd)
            {
                model.Id = NewId();
                return RetOK(model.Id, "新增成功");
            }
            else
            {
                return RetOK(string.Empty, "更新成功");
            }
        }
        /// <summary>
        /// 新增保存
        /// </summary>
        public virtual ApiResult<string> RoleAdd(Sys_Role model)
        {
            return DaRole.Add(model);
        }
        /// <summary>
        /// 编辑保存
        /// </summary>
        public virtual ApiResult<string> RoleEdit(Sys_Role model)
        {
            return DaRole.Update(model);
        }
        /// <summary>
        /// 删除
        /// </summary>
        public ApiResult RoleDel(Sys_Role model)
        {
            return DaRole.Del(model);
        }
        /// <summary>
        /// 获取所有角色
        /// </summary>
        public ApiResultList<Sys_Role> RoleGetData()
        {
            return DaRole.GetList(new ArgPageData());
        }

        #endregion

        #region 菜单树

        /// <summary>
        /// 菜单分类列表（非菜单的树形结构）
        /// </summary>
        public ApiResultList<Sys_RoleMenu> TreeGetData(string roleId)
        {
            var query = DB.CreateQuery<Sys_RoleMenu>();
            query.WhereAnd(s => s.RoleId == roleId);
            query.OrderBy(s => s.OrderNo);
            var r = DB.Query<Sys_RoleMenu>(query).ToList(true);
            return RetOK(r, r.Count);
        }

        ApiResult<string> VerifyTreeModel(Sys_RoleMenu model, bool isAdd)
        {
            if (model.MenuCaption.IsEmpty())
            {
                return ApiResult.RetErr(nameof(model.MenuCaption), "分类名称不能为空");
            }

            if (DB.QueryExist<Sys_RoleMenu>(s =>
                s.RoleId == model.RoleId && s.PId == model.PId && s.Id != model.Id && model.MenuCaption == model.MenuCaption))
            {
                return ApiResult.RetErr(nameof(model.MenuCaption), "分类名称已经存在");
            }
            if (isAdd)
            {
                model.Id = NewId();
                return RetOK(model.Id, "新增成功");
            }
            else
            {
                return RetOK(string.Empty, "更新成功");
            }
        }

        public ApiResult<string> TreeAdd(Sys_RoleMenu m)
        {
            var ret = VerifyTreeModel(m, true);
            if (!ret)
            {
                return ret;
            }
            if (DB.QueryExist<Sys_Menu>(s => s.PId == m.PId && s.MenuCaption == m.MenuCaption))
            {
                return ApiResult.RetErr(nameof(m.MenuCaption), "当前节点下菜单名称重复");
            }
            //if (DB.QueryExist<Sys_Menu>(s => s.PId == m.PId && s.IsMenu == true))
            //{
            //    return ApiResult.RetErr(string.Empty, "当前菜单分类已经分配菜单，不允许增加子级分类");
            //}
            DB.Insert(m);
            return ret;
        }

        public ApiResult<string> TreeEdit(Sys_RoleMenu m)
        {
            var ret = VerifyTreeModel(m, false);
            if (!ret)
            {
                return ret;
            }
            var r = DB.Update(m);
            if (r.RowCount == 1)
            {
                return ApiResult.RetOK(string.Empty, "更新成功");
            }
            return ret;
        }

        public ApiResult TreeChangeParentId(Sys_RoleMenu m)
        {
            ExecResult r;
            string tarPId = m.Tag?.ToString();
            if (tarPId == m.PId)
            {
                r = DB.UpdateByExpr<Sys_RoleMenu>(
                    s => s.PId == m.PId && s.OrderNo >= m.OrderNo,
                    "OrderNo = OrderNo + 1");
            }
            else
            {
                m.PId = tarPId;
                r = DB.Update(m);
            }
            if (r.RowCount == 1)
            {
                return ApiResult.RetOK("修改成功");
            }
            return ApiResult.RetOK("修改失败");
        }

        public ApiResult TreeDel(Sys_RoleMenu menu)
        {
            if (DB.QueryExist<Sys_RoleMenu>(s => s.PId == menu.Id))
            {
                return ApiResult.RetErr("请先移除所子级节点及菜单");
            }
            var ret = DB.Delete<Sys_RoleMenu>(s => s.Id == menu.Id);
            if (ret.RowCount == 1)
            {
                return ApiResult.RetOK("删除成功");
            }
            return ApiResult.RetErr("删除失败");
        }

        public ApiResult SwapOrderNo(ArgSwapOrderNo arg)
        {
            if (arg.SrcId.IsEmpty() || arg.SrcId.IsEmpty())
            {
                return RetOK("参数错误");
            }
            Sys_RoleMenu model = new Sys_RoleMenu();
            model.Id = arg.SrcId;
            model.OrderNo = arg.TarOrderNo;
            DB.Update(model);
            model.Id = arg.TarId;
            model.OrderNo = arg.SrcOrderNo;
            DB.Update(model);
            return RetOK("交换位置成功");
        }

        #endregion

        #region 角色菜单

        public ApiResultList<Sys_Menu> GetMenuTree()
        {
            var query = DB.CreateQuery<Sys_Menu>();
            query.OrderBy(s => s.OrderNo);
            var menuList = DB.Query<Sys_Menu>(query).ToList(true);
            return RetOK(menuList, menuList.Count);
        }

        ApiResult<string> VerifyMenuModel(Sys_RoleMenu model, bool isAdd)
        {
            if (model.MenuCaption.IsEmpty())
            {
                return ApiResult.RetErr(nameof(model.MenuCaption), "菜单标题不能为空");
            }
            if (model.MenuName.IsEmpty() || model.MenuId.IsEmpty())
            {
                return ApiResult.RetErr(nameof(model.MenuName), "菜单名称不能为空");
            }
            //if (DB.QueryExist<Sys_Role_Menu>(s => s.RoleId == model.RoleId && s.PId == model.PId && s.MenuName == model.MenuName && s.Id != model.Id))
            //{
            //    return ApiResult.RetErr(nameof(model.MenuName), "菜单已经存在当前角色下");
            //}
            if (isAdd)
            {
                model.Id = NewId();
                return RetOK(model.Id, "新增菜单成功");
            }
            else
            {
                return RetOK(string.Empty, "更新菜单成功");
            }
        }

        public ApiResult<string> AddRoleMenu(Sys_RoleMenu model)
        {
            var ret = VerifyMenuModel(model, true);
            if (!ret)
            {
                return ret;
            }
            model.IsMenu = true;
            DB.Insert(model);
            return ret;
        }

        public ApiResult<string> EditRoleMenu(Sys_RoleMenu model)
        {
            var ret = VerifyMenuModel(model, false);
            if (!ret) return ret;
            DB.Update(model);
            return ret;
        }

        public ApiResult DelRoleMenu(Sys_RoleMenu model)
        {
            var ret = DB.Delete<Sys_RoleMenu>(s => s.Id == model.Id);
            if (ret.RowCount == 1)
            {
                return ApiResult.RetOK("删除成功");
            }
            else
            {
                return ApiResult.RetOK("删除失败，记录不存在！");
            }
        }

        /// <summary>
        /// 根据父级Id获取所有子菜单
        /// </summary>
        public ApiResultList<Sys_RoleMenu> GetRoleMenus(ArgGetRoleMenus arg)
        {
            var query = DB.CreateQuery<Sys_RoleMenu>();
            query.WhereAnd(s => s.RoleId == arg.RoleId);
            if (arg.IsToorBar)
            {
                query.WhereAnd(s => s.ToolBarVisible == true);
            }
            else
            {
                query.WhereAnd(s => s.PId == arg.PId);
            }
            if (!arg.SearchVal.IsEmpty())
            {
                string likeStr = $"%{arg.SearchVal}%";
                query.WhereAnd(s =>
                    s.WEx_Like(s.MenuCaption, likeStr) ||
                    s.WEx_Like(s.MenuName, likeStr));
            }
            if (arg.IsToorBar)
            {
                query.OrderBy(s => s.ToolBarOrderNo);
            }
            else
            {
                query.OrderBy(s => s.OrderNo);
            }
            var rList = DB.Query<Sys_RoleMenu>(query).ToList();
            return RetOK(rList, 0);
        }

        #endregion
        ///// <summary>
        ///// 获取当前角色的所有菜单
        ///// </summary>
        //public ApiResultList<Sys_Role_Menu> GetMenuByRole()
        //{
        //    string roleId = CurrRoleId;
        //    var query = DB.CreateQuery<Sys_Role_Menu>();
        //    query.WhereAnd(s => s.RoleId == roleId);
        //    query.OrderBy(s => s.OrderNo);
        //    var r = DB.Query<Sys_Role_Menu>(query).ToList(true);
        //    return RetOK(r, r.Count);
        //}
        /// <summary>
        /// 修改菜单的排序号
        /// </summary>
        public ApiResult SetRoleMenuOrder(string id, int orderNo)
        {
            Sys_RoleMenu m = new Sys_RoleMenu
            {
                Id = id,
                OrderNo = orderNo
            };
            DB.Update(m);
            return RetOK("更新菜单排序完成");
        }
        /// <summary>
        /// 修改菜单工具栏的排序号
        /// </summary>
        public ApiResult SetRoleToolMenuOrder(string id, int orderNo)
        {
            Sys_RoleMenu m = new Sys_RoleMenu
            {
                Id = id,
                ToolBarOrderNo = orderNo
            };
            DB.Update(m);
            return RetOK("更新菜单排序完成");
        }

        public ApiResult SetOrderNo(string id, int orderNo)
        {
            Sys_RoleMenu menu = new Sys_RoleMenu
            {
                Id = id,
                OrderNo = orderNo
            };
            DB.Update(menu);
            return RetOK("更新排序成功");
        }

        public ApiResult SetParent(string srcId, string tarPId, int orderNo)
        {
            Sys_RoleMenu model = new Sys_RoleMenu
            {
                Id = srcId,
                PId = tarPId,
                OrderNo = orderNo
            };
            var ret = DB.Update(model);
            if (ret.RowCount == 1)
            {
                return RetOK("更新父级成功");
            }
            else
            {
                return RetOK("更新父级失败");
            }
        }
    }
}